package com.cyw.thread.threadpool.mythreadpool;

import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Author: Chenyw
 * @Date: 2022/09/21/10:26
 */
public class TestThread {
    //当前电影票余量
    private static int currentTickets = 300000;

    //加锁确保多线程场景下的线程安全
    private static Lock lock = new ReentrantLock();


    public static void main(String[] args) {

        long start = System.currentTimeMillis();

        /*
        ThreadPoolExecutor 参数详解
        *   corePoolSize : 初始线程数量
        *   maximumPoolSize : 最大线程数量
        *   keepAliveTime : 定义线程闲置回收时间
        *   TimeUnit unit : 与定义回收时间绑定时间单位 时分秒
        *       TimeUnit.DAYS;              //天
                TimeUnit.HOURS;             //小时
                TimeUnit.MINUTES;           //分钟
                TimeUnit.SECONDS;           //秒
                TimeUnit.MILLISECONDS;      //毫秒
                TimeUnit.MICROSECONDS;      //微妙
                TimeUnit.NANOSECONDS;       //纳秒
        *  workQueue :
        *   new ArrayBlockingQueue：基于数组的先进先出队列，此队列创建时必须指定大小
            new LinkedBlockingQueue：基于链表的先进先出队列，如果创建时没有指定此队列大小，则默认为 Integer.MAX_VALUE
            new SynchronousQueue：这个队列比较特殊，它不会保存提交的任务，而是将直接新建一个线程来执行新来的任务
        *
        *
        * */
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(6,12,5, TimeUnit.MINUTES,
                new ArrayBlockingQueue<Runnable>(5));
        for (int i = 0; i <300000 ; i++) {
            Future<Object> submit = threadPoolExecutor.submit(new Callable<Object>() {
                @Override
                public Object call() throws Exception {
                    return saleTickets();    //调用方法体
                }
            });
            try {
                System.out.println(submit.get());
            }catch (Exception e){

            }finally {

            }
        }
        //关闭线程池
        threadPoolExecutor.shutdown();


        long end = System.currentTimeMillis();

        System.out.println(end-start);
    }

     static String saleTickets(){
        lock.lock();
        try {
            if (currentTickets > 0 ){
                currentTickets--;
                return Thread.currentThread().getName()+"窗口出票成功！当前剩余："+currentTickets;
            }else {
                return Thread.currentThread().getName()+"窗口出票失败！当前剩余："+currentTickets;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
        return "当前人数较多，请稍后重试";
    }
}
